package com.derbysoft.lowcostadapter.dswitch3.translate.impl;


import com.derbysoft.dswitch.dto.hotel.avail.*;
import com.derbysoft.dswitch.dto.hotel.common.*;
import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailRequest;
import com.derbysoft.dswitch.remote.hotel.dto.HotelAvailResponse;
import com.derbysoft.lowcostadapter.commons.model.RateCache;
import com.derbysoft.lowcostadapter.commons.model.RoomType;
import com.derbysoft.lowcostadapter.commons.redis.service.RoomTypeCacheService;
import com.derbysoft.lowcostadapter.commons.utils.DateTimeUtils;
import com.derbysoft.lowcostadapter.dswitch2.translator.Translator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by: jason
 * Date: 2012-06-29
 */
@Component("ds3AvailResponseTranslator")
public class DS3AvailResponseTranslator implements Translator<List<RateCache>, HotelAvailResponse, HotelAvailRequest> {

    @Autowired
    private RoomTypeCacheService roomTypeCacheService;

    @Override
    public HotelAvailResponse translate(List<RateCache> rateCaches, HotelAvailRequest request) {
        HotelAvailResponse hotelAvailResponse = new HotelAvailResponse();
        hotelAvailResponse.setTaskId(request.getHeader().getTaskId());
        HotelAvailRS hotelAvailRS = new HotelAvailRS();
        hotelAvailRS.setHotelAvailRoomStaysList(createAvailRoomStays(rateCaches, request));
        hotelAvailResponse.setHotelAvailRS(hotelAvailRS);
        if (CollectionUtils.isEmpty(hotelAvailResponse.getHotelAvailRS().getHotelAvailRoomStaysList())) {
            hotelAvailRS.setNoAvailHotelsList(request.getHotelAvailRQ().getAvailCriteria().getHotelCodesList());
        }
        return hotelAvailResponse;
    }

    private List<HotelAvailRoomStayDTO> createAvailRoomStays(List<RateCache> rateCaches, HotelAvailRequest request) {
        String hotelPassport = request.getHotelAvailRQ().getAvailCriteria().getHotelCodesList().get(0);
        StayDateRangeDTO stayDateRangeDTO = request.getHotelAvailRQ().getAvailCriteria().getStayDateRange();
        Map<String, AvailRoomStayDTO> roomStayMap = new LinkedHashMap<String, AvailRoomStayDTO>();
        for (RateCache rateCache : rateCaches) {
            String key = rateCache.getMealBasis().getMealBaseID() + "_" + rateCache.getPropertyRoomTypeID();
            if (roomStayMap.containsKey(key)) {
                continue;
            }
            roomStayMap.put(key, createRoomStay(rateCache, stayDateRangeDTO));
        }
        List<HotelAvailRoomStayDTO> hotelAvailRoomStayDTOs = new ArrayList<HotelAvailRoomStayDTO>();
        HotelAvailRoomStayDTO hotelAvailRoomStayDTO = new HotelAvailRoomStayDTO();
        hotelAvailRoomStayDTO.setHotelCode(hotelPassport);
        hotelAvailRoomStayDTO.setRoomStaysList(new ArrayList<AvailRoomStayDTO>(roomStayMap.values()));
        hotelAvailRoomStayDTOs.add(hotelAvailRoomStayDTO);
        return hotelAvailRoomStayDTOs;
    }

    private AvailRoomStayDTO createRoomStay(RateCache rateCache, StayDateRangeDTO stayDateRangeDTO) {
        AvailRoomStayDTO availRoomStayDTO = new AvailRoomStayDTO();
        availRoomStayDTO.setLanguage("EN_US");
        availRoomStayDTO.setRatePlan(createRatePlan(rateCache));
        availRoomStayDTO.setRoomType(createRoomType(rateCache));
        availRoomStayDTO.setCurrency(AbstractDSwitch3Translator.DEFAULT_CURRENCY);
        availRoomStayDTO.setRoomRate(createRoomRate(rateCache, stayDateRangeDTO));
        return availRoomStayDTO;
    }

    private RoomRateDTO createRoomRate(RateCache rateCache, StayDateRangeDTO stayDateRangeDTO) {
        RoomRateDTO roomRateDTO = new RoomRateDTO();
        roomRateDTO.setRatesList(createRates(rateCache, stayDateRangeDTO));
        return roomRateDTO;
    }

    private List<RateDTO> createRates(RateCache rateCache, StayDateRangeDTO stayDateRangeDTO) {
        ArrayList<RateDTO> rateDTOs = new ArrayList<RateDTO>();
        RateDTO rateDTO = new RateDTO();
        rateDTO.setAmountBeforeTax(rateCache.getRate().doubleValue());
        rateDTO.setAmountBeforeTax(rateCache.getRate().doubleValue());
        rateDTO.setDateRange(createDateRange(stayDateRangeDTO));
        rateDTOs.add(rateDTO);
        return rateDTOs;
    }

    private DateRangeDTO createDateRange(StayDateRangeDTO stayDateRangeDTO) {
        DateRangeDTO dateRangeDTO = new DateRangeDTO();
        dateRangeDTO.setStart(stayDateRangeDTO.getCheckin());
        dateRangeDTO.setEnd(DateTimeUtils.formatDate(DateTimeUtils.offsetDays(DateTimeUtils.parse(stayDateRangeDTO.getCheckout()), -1)));
        return dateRangeDTO;
    }

    private RoomTypeDTO createRoomType(RateCache rateCache) {
        RoomTypeDTO roomTypeDTO = new RoomTypeDTO();
        roomTypeDTO.setCode(String.valueOf(rateCache.getPropertyRoomTypeID()));
        RoomType roomType = roomTypeCacheService.loadByRoomTypeId(rateCache.getPropertyRoomTypeID());
        roomTypeDTO.setName(roomType == null ? String.valueOf(rateCache.getPropertyRoomTypeID()) : roomType.getDescription());
        return roomTypeDTO;
    }

    private RatePlanDTO createRatePlan(RateCache rateCache) {
        RatePlanDTO ratePlanDTO = new RatePlanDTO();
        ratePlanDTO.setCode(String.valueOf(rateCache.getMealBasis().getMealBaseID()));
        ratePlanDTO.setName(rateCache.getMealBasis().getDescription());
        ratePlanDTO.setPaymentType(PaymentType.PREPAY);
        ratePlanDTO.setFreeMeal(createFreeMeal(rateCache));
        return ratePlanDTO;
    }

    private FreeMealDTO createFreeMeal(RateCache rateCache) {
        FreeMealDTO freeMealDTO = new FreeMealDTO();
        DSwitch3MealBasis dswitch3MealBasis =
                DSwitch3MealBasis.fromID(rateCache.getMealBasis().getMealBaseID());
        freeMealDTO.setType(dswitch3MealBasis.getFreeMealType());
        freeMealDTO.setDescription(dswitch3MealBasis.getDescription());
        return freeMealDTO;
    }
}
